home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / cit.arc / ROOMA.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-01-22  |  23.8 KB  |  770 lines

  1. /************************************************************************/
  2. /*                rooma.c                 */
  3. /*        room code for Citadel bulletin board system        */
  4. /************************************************************************/
  5.  
  6. /************************************************************************/
  7. /*                history                 */
  8. /*                                    */
  9. /* 85Nov17 HAW    <U>ngoto command.                    */
  10. /* 85Nov15 HAW    Update for MS-DOS library.                */
  11. /* 85Sep08 HAW    Cosmetic for known rooms: ':' --> ']'.            */
  12. /* 85Jul06 HAW    Add searchRooms() function.                */
  13. /* 85Jul01 HAW    Add formatFile() for formatting host files.        */
  14. /* 85May23 HAW    Fix listRoom() & gotoRoom() for rolled new messages.    */
  15. /* 85Mar20 HAW    Add stuff to handle time stamped messages.        */
  16. /* 85Feb21 HAW    Starting to implement download/upload.            */
  17. /* 85Jan30 HAW    Fix new message counting problem in dumpRoom().     */
  18. /* 85Jan21 HAW    Change systat() to print out time if under MSDOS.    */
  19. /* 85Jan20 HAW    Insert code to call system clock if under MSDOS.    */
  20. /* 84Sep14 HAW    System dies after 4,294,967,295 messages.  Take note!    */
  21. /* 84Sep14 HAW    Rewrite dumpRoom() for readability.            */
  22. /* 84Aug30 HAW    Here we leap into <gulp> MS-DOS.            */
  23. /* 84Aug23 JLS & HAW  JLS's <F>orget Room Scheme implemented.        */
  24. /* 84Jul12 JLS & HAW  gotoRoom() and dumpRoom() modified for <S>kip.    */
  25. /* 84Jun23 HAW    Files now checked for CP/M R/O status.            */
  26. /* 84Jun23 HAW & JLS  Unused locals are zapped                */
  27. /* 84Apr04 HAW    Start 1.50a update                    */
  28. /* 83Feb24    Insert check for insufficient RAM, externs too low.    */
  29. /* 82Dec06 CrT    2.00 release.                        */
  30. /* 82Nov05 CrT    main() splits off to become citadel.c            */
  31. /************************************************************************/
  32.  
  33. #include "ctdl.h"
  34.  
  35. /************************************************************************/
  36. /*                Contents                */
  37. /*                                    */
  38. /*    dumpRoom()        tells us # new messages etc        */
  39. /*    fDir()            prints out a filename for a dir listing */
  40. /*    fillMailRoom()        set up Mail> from log record        */
  41. /*    formatFile()        formats a hostfile (unlike transmitFile)*/
  42. /*    gotoRoom()        handles "g(oto)" command for menu    */
  43. /*    initCitadel()        system startup initialization        */
  44. /*    listRooms()        lists known rooms            */
  45. /*    openFile()        opens a .sys file            */
  46. /*    retRoom()        handle Ungoto command            */
  47. /*    roomExists()        returns slot# of named room else ERROR    */
  48. /*    searchRooms()        searches room list for matching string    */
  49. /*    setSpace()        set default disk and user#        */
  50. /*    setUp()                             */
  51. /*    systat()        shows current system status        */
  52. /*    wildCard()        expands ambiguous filenames        */
  53. /*                                    */
  54. /************************************************************************/
  55.  
  56. /************************************************************************/
  57. /*           external variable declarations in ROOMA.C        */
  58. /************************************************************************/
  59. long          FDSectCount;        /* For accumulating dir. size    */
  60. char          debug;            /* debug flag            */
  61. char          *baseRoom;
  62. int          lastRoom;         /* last room visited        */
  63. int          lastPtr;
  64.  
  65. /************************************************************************/
  66. /*           external variable definitions for ROOMA.C        */
  67. /************************************************************************/
  68. extern struct config    cfg;        /* A buncha variables        */
  69. extern struct lTable    *logTab;    /* RAM index of pippuls     */
  70. extern struct logBuffer logBuf;     /* Pippul buffer        */
  71. extern struct msgB    msgBuf;     /* message buffer        */
  72. extern FILE        *logfl;     /* log file descriptor        */
  73. extern FILE        *msgfl;     /* Message file descriptor    */
  74. extern FILE        *msgfl2;    /* Another for auto backup    */
  75. extern FILE        *netfl;     /* Net file            */
  76. extern struct rTable    roomTab[MAXROOMS]; /* RAM index of rooms    */
  77. extern struct aRoom    roomBuf;    /* room buffer            */
  78. extern FILE        *roomfl;    /* file descriptor for rooms    */
  79. extern int        thisRoom;    /* room currently in roomBuf    */
  80. extern char        loggedIn;    /* Are we logged in?        */
  81. extern char        expert;     /* Are we experienced??     */
  82. extern char        echo;        /* output flag            */
  83. extern char        usingWCprotocol;/* WC flag            */
  84. extern char        prevChar;    /* Last char out        */
  85. extern char        termLF;     /* Need LF's?            */
  86. extern char        termUpper;    /* Only uppercase? Aw, foo    */
  87. extern char        aide;        /* aide?            */
  88. extern char        sendTime;    /* Send time message made?    */
  89. extern char        onConsole;    /* on console?            */
  90. extern char        whichIO;    /* where is the I/O?        */
  91. extern unsigned char    termNulls;    /* How many nulls?        */
  92. extern unsigned char    termWidth;    /* What's da termwidth?     */
  93. extern int        thisSlot;    /* Current log slot        */
  94. extern char        outFlag;
  95. extern char        nextDay;    /* System up before bailout?    */
  96. extern int        upDay;
  97. extern int        timeCrash;
  98. extern char        heldMess;
  99. extern char        oldToo;
  100. extern label        oldTarget;    /* Room to move messages to    */
  101.  
  102. /************************************************************************/
  103. /*           external function definitions for ROOMA.C        */
  104. /************************************************************************/
  105. char toUpper();
  106. FILE *fopen();
  107. char *malloc();
  108.  
  109. /************************************************************************/
  110. /*    dumpRoom() tells us # new messages etc                */
  111. /************************************************************************/
  112. dumpRoom()
  113. {
  114.     char  hasSkipped;
  115.     label str;
  116.     int   fDir();
  117.     int   i, count, newCount;
  118.  
  119.     for (newCount = count = i = 0;   i < MSGSPERRM;   i++) {
  120.                 /* Msg is still in system?  Count it.    */
  121.     if (roomBuf.msg[i].rbmsgNo >= cfg.oldest) {
  122.         count++;
  123.  
  124.         /* don't boggle -- just checking against newest as of */
  125.         /* the last time we were  in this room:          */
  126.         if (roomBuf.msg[i].rbmsgNo >
  127.               logBuf.lbvisit[ logBuf.lbgen[thisRoom] & CALLMASK ]) {
  128.         newCount++;
  129.         }
  130.     }
  131.     }
  132.     if (!loggedIn && thisRoom == MAILROOM)    /* Kludge for new users */
  133.     newCount = count = 1;            /* So they see intro.    */
  134.  
  135.     mPrintf(" %d messages\n ", count);
  136.     if ((thisRoom == MAILROOM || loggedIn) && newCount > 0)
  137.     mPrintf(" %d new\n", newCount);
  138.  
  139.     if ((roomBuf.rbflags.MSDOSDIR == 1) && !expert) {
  140.     /* list directory also: */
  141.     doCR();
  142.     wildCard(fDir, "*.*");
  143.     }
  144.  
  145.     for (i = LOBBY, hasSkipped = FALSE; i < MAXROOMS; i++)
  146.     if (roomTab[i].rtflags.INUSE == 1 &&
  147.            roomTab[i].rtgen == (logBuf.lbgen[i] >> GENSHIFT)) {
  148.         if (roomTab[i].rtflags.SKIP == 1)
  149.         hasSkipped = TRUE;
  150.         else
  151.         if (roomTab[i].rtlastMessage > (
  152.             logBuf.lbvisit[logBuf.lbgen[i] & CALLMASK] + 1))
  153.             break;
  154.     }
  155.  
  156.     if (i == MAXROOMS && hasSkipped) {
  157.     mPrintf("\n Skipped rooms: \n ");
  158.     for (i = LOBBY; i < MAXROOMS; i++)    /* No need to match gen #s. */
  159.         if (roomTab[i].rtflags.SKIP == 1 &&
  160.                roomTab[i].rtflags.INUSE == 1) {
  161.         roomTab[i].rtflags.SKIP = 0;               /* Clear. */
  162.         strCpy(str, roomTab[i].rtname);
  163.         if (roomTab[i].rtflags.MSDOSDIR == 1) strcat(str, "]");
  164.         else                    strcat(str, ">");
  165.         if (roomTab[i].rtflags.PUBLIC == 0) strcat(str, "*");
  166.         mPrintf(" %s ", str);
  167.         }
  168.     }
  169. }
  170.  
  171. /************************************************************************/
  172. /*    fDir() prints out one filename and size, for a dir listing   */
  173. /************************************************************************/
  174. fDir(fileName)
  175. char *fileName;
  176. {
  177.     FILE *temp;
  178.     long fseek(), size, Sectors;
  179.  
  180.     outFlag = OUTOK;
  181.     if ((temp = fopen(fileName, "rb")) == NULL)
  182.     return mPrintf("\n ?Can't find file size for %s!", fileName);
  183.  
  184.     size    = (fseek(temp, -1l, 2)+1);
  185.     Sectors    = ((size + 127) / SECTSIZE);
  186.     FDSectCount += Sectors;
  187.  
  188.     mPrintf("%-15s%5ld%2c", fileName, Sectors, ' ');
  189.     mAbort();        /* chance to next(!)/pause/skip */
  190.     fclose(temp);
  191. }
  192.  
  193. /************************************************************************/
  194. /*    fillMailRoom()                            */
  195. /************************************************************************/
  196. fillMailRoom()
  197. {
  198.     int i;
  199.  
  200.     /* mail room -- copy messages in logBuf to room: */
  201.     for (i = 0;  i < MSGSPERRM;  i++) {
  202.     roomBuf.msg[i].rbmsgNo     = 0l;    /* Marks "no" msg */
  203.     roomBuf.msg[i].rbmsgLoc  = 0 ;    /* Jest fer fun   */
  204.     }
  205.     for (i = 0;  i < MAILSLOTS;  i++) {
  206.     if (i == MSGSPERRM)   break;  /* for MSGSPRRM < MAILSLOTS */
  207.     roomBuf.msg[i].rbmsgLoc  = logBuf.lbslot[i];
  208.     roomBuf.msg[i].rbmsgNo     = logBuf.lbId[i]  ;
  209.     }
  210.     noteRoom();
  211. }
  212.  
  213. /************************************************************************/
  214. /*    formatFile() dumps a host file WITH formatting            */
  215. /************************************************************************/
  216. formatFile(filename)
  217. char *filename;
  218. {
  219. #define CPMEOF    26            /* For CP/M files, EOF == ^Z    */
  220. #define LINELEN 150
  221.     char fname[NAMESIZE], *fgets();
  222.     FILE *fbuf;
  223.     char line[LINELEN];
  224.  
  225.     outFlag    = OUTOK;
  226.  
  227.     unspace(filename, fname);
  228.  
  229.     if ((fbuf = fopen(fname, "r")) == NULL) {
  230.     mPrintf("\n No %s.\n", fname);
  231.     return(ERROR);
  232.     }
  233.  
  234.     doCR();
  235.  
  236.     while (fgets(line, LINELEN-1, fbuf) != NULL) {
  237.     mFormat(line);
  238.     if (outFlag == OUTNEXT) break;
  239.     }
  240.  
  241.     fclose(fbuf);
  242. }
  243.  
  244. /************************************************************************/
  245. /*    gotoRoom() is the menu fn to travel to a new room        */
  246. /*    returns TRUE if room is Lobby>, else FALSE            */
  247. /************************************************************************/
  248. gotoRoom(nam, mode)
  249. char *nam, mode;
  250. {
  251.     int  i, foundit, roomNo;
  252.     int  lPtr, lRoom;
  253.  
  254.     lRoom = thisRoom;
  255.     lPtr  = (logBuf.lbgen[thisRoom] & CALLMASK);
  256.  
  257.     if (strLen(nam) == 0) {
  258.  
  259.     foundit = FALSE;    /* leaves us in Lobby> if nothing found */
  260.     if (mode != 'S') {
  261.         if (loggedIn)
  262.         logBuf.lbgen[thisRoom] = roomBuf.rbgen << GENSHIFT;
  263.         roomTab[thisRoom].rtflags.SKIP = 0;
  264.     }
  265.  
  266.     for (i = 0; i<MAXROOMS    &&  !foundit; i++) {
  267.         if (
  268.         roomTab[i].rtflags.INUSE == 1
  269.         &&
  270.         (roomTab[i].rtgen == (logBuf.lbgen[i] >> GENSHIFT) || aide)
  271.         &&
  272.         roomTab[i].rtflags.SKIP == 0
  273.         ) {
  274.         if (roomTab[i].rtlastMessage >
  275.             logBuf.lbvisit[logBuf.lbgen[i] & CALLMASK] &&
  276.             roomTab[i].rtlastMessage >= cfg.oldest) {
  277.  
  278.             if (i != thisRoom && (i != AIDEROOM || aide)) {
  279.             foundit  = i;
  280.             }
  281.         }
  282.         }
  283.     }
  284.  
  285.     lastRoom = lRoom;
  286.     lastPtr  = lPtr;
  287.     getRoom(foundit);
  288.     mPrintf("%s\n ", roomBuf.rbname);
  289.     } else {
  290.  
  291.     /* non-empty room name, so now we look for it: */
  292.     if (
  293.         (roomNo = roomExists(nam)) == ERROR
  294.         ||
  295.         (roomNo==AIDEROOM  &&  !aide)
  296.     ) {
  297.         mPrintf(" ?no %s room\n", nam);
  298.     } else {
  299.         if (mode != 'S') {
  300.         if (loggedIn)
  301.             logBuf.lbgen[thisRoom] = roomBuf.rbgen << GENSHIFT;
  302.         roomTab[thisRoom].rtflags.SKIP = 0;
  303.         }
  304.         lastRoom = lRoom;        /* For Ungoto            */
  305.         lastPtr  = lPtr;
  306.         getRoom(roomNo);
  307.  
  308.         /* if may have been unknown... if so, note it:    */
  309.         if ((logBuf.lbgen[thisRoom] >> GENSHIFT) != roomBuf.rbgen) {
  310.         logBuf.lbgen[thisRoom] = (
  311.             (roomBuf.rbgen << GENSHIFT) +
  312.             (MAXVISIT -1)
  313.         );
  314.         }
  315.     }
  316.     }
  317.  
  318.     setUp(FALSE);
  319.     dumpRoom();
  320. }
  321.  
  322. /************************************************************************/
  323. /*    initCitadel() does not reformat data files            */
  324. /************************************************************************/
  325. initCitadel()
  326. {
  327.     char *msgFile;
  328.     char *msg2File;
  329.     char *roomFile;
  330.     char *logFile;
  331.     char *netFile;
  332.     char *mon;
  333.     int  yr, hr, mn;
  334.  
  335.     if (!readSysTab(TRUE))
  336.     exit(CRASH_EXIT);/* No system table? Tacky, tacky*/
  337.     cfg.weAre = CITADEL;
  338.     setSpace(cfg.homeDisk, "");
  339.  
  340.     strCpy(oldTarget, "Aide");
  341.  
  342.     baseRoom = &cfg.codeBuf[cfg.bRoom];
  343.  
  344.     setUp(TRUE);
  345.  
  346.     /* we initmodem at beginning & end both...*/
  347.     modemInit();
  348.     getDate(&yr, &mon, &upDay, &hr, &mn);
  349.     timeCrash = hr + cfg.hourOut;
  350.     if ((nextDay = (timeCrash > 23))) timeCrash %= 24;
  351.  
  352. #ifndef MSDOS
  353.     if (!cfg.clock)   interpret(cfg.pInitDate);
  354. #endif
  355.  
  356.     /* open message files: */
  357.     msgFile    = "a:ctdlmsg.sys";
  358.     msg2File    = "a:ctdlmsg.sys";
  359.     logFile    = "a:ctdllog.sys";
  360.     roomFile    = "a:ctdlroom.sys";
  361.     netFile    = "a:ctdlnet.sys";
  362.     *msgFile   += cfg.msgDisk;
  363.     *roomFile  += cfg.sysDisk;
  364.     *logFile   += cfg.sysDisk;
  365.     *netFile   += cfg.netDisk;
  366.     if (cfg.mirror) {
  367.     *msg2File += cfg.mbkpDisk;
  368.     openFile(msg2File,  &msgfl2);
  369.     }
  370.     openFile(msgFile,  &msgfl );
  371.     openFile(roomFile, &roomfl);
  372.     openFile(logFile,  &logfl );
  373.     openFile(netFile,  &netfl );
  374.  
  375.     getRoom(LOBBY);    /* load Lobby>    */
  376.     modemInit();
  377.     whichIO = MODEM;
  378.     setUp(FALSE);
  379. }
  380.  
  381. /************************************************************************/
  382. /*    listRooms() lists known rooms                    */
  383. /************************************************************************/
  384. listRooms(doDull)
  385. char doDull;    /* ALMOST_ALL to list unforgotten rooms only    */
  386. {
  387.     char str[NAMESIZE+3];
  388.     char boringRooms, doBoringRooms, hasUnseenStuff, shownHidden;
  389.     int  i, Equal;
  390.  
  391.     mPrintf((doDull == FORGOT) ? "\n Forgotten public rooms:\n " :
  392.                  "\n Rooms with unread messages:\n ");
  393.     Equal    = TRUE;
  394.     shownHidden = FALSE;
  395.     boringRooms = FALSE;
  396.     doBoringRooms = (doDull == FORGOT) ? FORGOT : UNREAD;
  397.     for (; doBoringRooms <= doDull;  doBoringRooms++) {
  398.     for (i = 0; i < MAXROOMS;  i++) {
  399.         Equal = (roomTab[i].rtgen == (logBuf.lbgen[i] >> GENSHIFT));
  400.         if ((roomTab[i].rtflags.INUSE == 1) && (debug || aide || Equal)) {
  401.         /* do only rooms with unseen messages first pass,  */
  402.         /* only rooms without unseen messages second pass: */
  403.         hasUnseenStuff    =  (roomTab[i].rtlastMessage > cfg.oldest &&
  404.             roomTab[i].rtlastMessage >= (
  405.             logBuf.lbvisit[ logBuf.lbgen[i] & CALLMASK ]+1));
  406.         if (!hasUnseenStuff)   boringRooms  = TRUE;
  407.  
  408.         if (doDull != FORGOT             &&
  409.             ((!doBoringRooms &&  hasUnseenStuff)  ||
  410.             ( doBoringRooms && !hasUnseenStuff))
  411.         ) {
  412.             strCpy(str, roomTab[i].rtname);
  413.  
  414.             if (roomTab[i].rtflags.MSDOSDIR == 1) strcat(str, "]");
  415.             else                strcat(str, ">");
  416.  
  417.             if (roomTab[i].rtflags.PUBLIC == 0) {
  418.             strcat(str, "*");
  419.             shownHidden    = TRUE;
  420.             }
  421.             mPrintf(" %s ", str);
  422.         }
  423.         }
  424.         else {
  425.         if (!Equal && (doDull == FORGOT &&
  426.                    roomTab[i].rtflags.INUSE  == 1 &&
  427.                    roomTab[i].rtflags.PUBLIC == 1)) {
  428.             mPrintf(" %s%c ", roomTab[i].rtname,
  429.                 (roomTab[i].rtflags.MSDOSDIR == 1) ? ']' : '>');
  430.         }
  431.         Equal = TRUE;
  432.         }
  433.     }
  434.     if (boringRooms && !doBoringRooms  && doDull == ALMOST_ALL)  {
  435.         mPrintf("\n No unseen msgs in:\n ");
  436.     }
  437.     }
  438.     if (!expert && shownHidden) mPrintf("\n \n * => hidden room\n ");
  439. }
  440.  
  441. /************************************************************************/
  442. /*    openFile() opens one of the .sys files.             */
  443. /************************************************************************/
  444. openFile(filename, fd)
  445. char *filename;
  446. FILE **fd;
  447. {
  448.     /* open message file */
  449.     if ((*fd = fopen(filename, "rwb")) == NULL) {
  450.     printf("?no %s", filename);
  451.     exit(SYSOP_EXIT);
  452.     }
  453. }
  454.  
  455. /************************************************************************/
  456. /*    retRoom() Ungoto command                    */
  457. /************************************************************************/
  458. retRoom()
  459. {
  460.     getRoom(lastRoom);
  461.     logBuf.lbgen[thisRoom] = (logBuf.lbgen[thisRoom] & (~CALLMASK)) + lastPtr;
  462.     lastRoom = -1;
  463. }
  464.  
  465. /************************************************************************/
  466. /*    roomExists() returns slot# of named room else ERROR        */
  467. /************************************************************************/
  468. int roomExists(room)
  469. char *room;
  470. {
  471.     int i;
  472.  
  473.     for (i = 0;  i < MAXROOMS;    i++) {
  474.     if (
  475.         roomTab[i].rtflags.INUSE == 1   &&
  476.         strCmpU(room, roomTab[i].rtname) == SAMESTRING
  477.     ) {
  478.         return(i);
  479.     }
  480.     }
  481.     return(ERROR);
  482. }
  483.  
  484. /************************************************************************/
  485. /*    searchRooms() searches for user string in list of rooms     */
  486. /************************************************************************/
  487. searchRooms()
  488. {
  489.     label target;
  490.     char  str[NAMESIZE+5];
  491.     int   i;
  492.     char  Equal, *endbuf, *matchString();
  493.  
  494.     getNormStr("", target, NAMESIZE, ECHO);
  495.  
  496.     mPrintf("Matching rooms:\n ");
  497.     outFlag = OUTOK;
  498.  
  499.     for (i = 0; i < MAXROOMS;  i++) {
  500.     Equal = (roomTab[i].rtgen == (logBuf.lbgen[i] >> GENSHIFT));
  501.     if ((roomTab[i].rtflags.INUSE == 1) && (debug || aide || Equal)) {
  502.         for (endbuf = roomTab[i].rtname; *endbuf; endbuf++);
  503.         if (matchString(roomTab[i].rtname, target, endbuf) != ERROR) {
  504.         strCpy(str, roomTab[i].rtname);
  505.  
  506.         if (roomTab[i].rtflags.MSDOSDIR == 1) strcat(str, "]");
  507.         else                      strcat(str, ">");
  508.  
  509.         if (roomTab[i].rtflags.PUBLIC == 0) {
  510.             strcat(str, "*");
  511.         }
  512.         mPrintf(" %s ", str);
  513.         }
  514.     }
  515.     }
  516. }
  517.  
  518. /************************************************************************/
  519. /*    setSpace() moves us to a disk and directory            */
  520. /************************************************************************/
  521. #define SETDISK     14
  522. setSpace(disk, dir)
  523. char disk;
  524. char *dir;
  525. {
  526.     bdos(SETDISK, disk);
  527.     cfg.ourDisk     = disk;
  528.  
  529.     if (strCmp(dir, "") == SAMESTRING) {
  530.     strCpy(cfg.ourUser, "..");
  531.     }
  532.     else {
  533.     strCpy(cfg.ourUser, dir);
  534.     if (chdir(dir) == EOF) {
  535.         mPrintf("?Directory not present!\n ");
  536.         setSpace(cfg.homeDisk, "");
  537.         return FALSE;
  538.     }
  539.     }
  540.     return TRUE;
  541. }
  542.  
  543. /************************************************************************/
  544. /*    setUp()                             */
  545. /************************************************************************/
  546. setUp(justIn)
  547. char justIn;
  548. {
  549.     int g, i, j, ourSlot;
  550.  
  551.     echo        = BOTH;     /* just in case         */
  552.  
  553.     if (!loggedIn)   {
  554.     prevChar    = ' ';
  555.     termWidth   = 32;
  556.     termLF        = TRUE;
  557.     termUpper   = FALSE;
  558.     termNulls   = 5;
  559.     expert        = FALSE;
  560.     aide        = FALSE;
  561.     sendTime    = TRUE;
  562.     oldToo        = FALSE;
  563.  
  564.     if (justIn)   {
  565.         /* set up logBuf so everything is new...        */
  566.         lastRoom = -1;
  567.             heldMess = FALSE;
  568.         for (i = 0; i < MAXVISIT;  i++)  logBuf.lbvisit[i] = cfg.oldest;
  569.  
  570.         /* no mail for anonymous folks: */
  571.         roomTab[MAILROOM].rtlastMessage = cfg.newest;
  572.         for (i = 0; i < MAILSLOTS;    i++)   logBuf.lbId[i]  = 0l;
  573.  
  574.         logBuf.lbname[0] = 0;
  575.  
  576.         for (i = 0; i < MAXROOMS;  i++) {
  577.         if (roomTab[i].rbflags.PUBLIC == 1) {
  578.             /* make public rooms known: */
  579.             g            = roomTab[i].rtgen;
  580.             logBuf.lbgen[i] = (g << GENSHIFT) + (MAXVISIT-1);
  581.         } else {
  582.             /* make private rooms unknown: */
  583.             g            = (roomTab[i].rtgen + (MAXGEN-1)) % MAXGEN;
  584.             logBuf.lbgen[i] = (g << GENSHIFT) + (MAXVISIT-1);
  585.         }
  586.         }
  587.     }
  588.     } else {
  589.     /* loggedIn: */
  590.     termWidth   = logBuf.lbwidth;
  591.     termNulls   = logBuf.lbnulls;
  592.     termLF        = (logBuf.lbflags.LFMASK == 1) ? TRUE : FALSE ;
  593.     termUpper   = (logBuf.lbflags.UCMASK == 1) ? TRUE : FALSE ;
  594.     expert        = (logBuf.lbflags.EXPERT == 1) ? TRUE : FALSE ;
  595.     aide        = (logBuf.lbflags.AIDE   == 1) ? TRUE : FALSE ;
  596.     sendTime    = (logBuf.lbflags.TIME   == 1) ? TRUE : FALSE ;
  597.     oldToo        = (logBuf.lbflags.OLDTOO == 1) ? TRUE : FALSE ;
  598.  
  599.     if (justIn)   {
  600.         lastRoom = -1;
  601.         heldMess = FALSE;
  602.         /* set gen on all unknown rooms  --  INUSE or no: */
  603.         for (i = 0;  i < MAXROOMS;    i++) {
  604.         if (roomTab[i].rtflags.PUBLIC == 0) {
  605.             /* it is private -- is it unknown? */
  606.             if (((logBuf.lbgen[i] >> GENSHIFT) != roomTab[i].rtgen) ||
  607.              (!aide && i == AIDEROOM)
  608.                ) {
  609.             /* yes -- set    gen = (realgen-1) % MAXGEN */
  610.             j = (roomTab[i].rtgen + (MAXGEN-1)) % MAXGEN;
  611.             logBuf.lbgen[ i ] =  (j << GENSHIFT) + (MAXVISIT-1);
  612.             }
  613.         }
  614.         else if ((logBuf.lbgen[i] >> GENSHIFT) != roomTab[i].rtgen)  {
  615.             /* newly created public room -- remember to visit it; */
  616.             j = roomTab[i].rtgen - (logBuf.lbgen[i] >> GENSHIFT);
  617.             if (j < 0)
  618.             g = -j;
  619.             else
  620.             g = j;
  621.             if (g != FORGET_OFFSET) {
  622.             logBuf.lbgen[i] = (roomTab[i].rtgen << GENSHIFT) +1;
  623.             }
  624.         }
  625.         }
  626.         /* special kludge for Mail> room, to signal new mail:   */
  627.         roomTab[MAILROOM].rtlastMessage = logBuf.lbId[MAILSLOTS-1];
  628.  
  629.         /* slide lbvisit array down and change lbgen entries to match: */
  630.         for (i = (MAXVISIT - 2);  i;  i--) {
  631.         logBuf.lbvisit[i] = logBuf.lbvisit[i-1];
  632.         }
  633.         logBuf.lbvisit[(MAXVISIT - 1)]    = cfg.oldest;
  634.         for (i = 0;  i < MAXROOMS;    i++) {
  635.         if ((logBuf.lbgen[i] & CALLMASK)  <  (MAXVISIT-2)) {
  636.             logBuf.lbgen[i]++;
  637.         }
  638.         }
  639.  
  640.         /* Slide entry to top of log table: */
  641.         ourSlot = logTab[thisSlot].ltlogSlot;
  642.         slideltab(0, thisSlot);
  643.  
  644.         logTab[0].ltpwhash        = hash(logBuf.lbpw);
  645.         logTab[0].ltnmhash        = hash(logBuf.lbname);
  646.         logTab[0].ltlogSlot     = ourSlot;
  647.         logTab[0].ltnewest        = cfg.newest;
  648.     }
  649.     }
  650.     logBuf.lbvisit[0]    = cfg.newest;
  651.  
  652.     onConsole    = (whichIO == CONSOLE);
  653.     if (thisRoom == MAILROOM)    fillMailRoom();
  654. }
  655.  
  656. /************************************************************************/
  657. /*    systat() prints out current system status            */
  658. /************************************************************************/
  659. systat()
  660. {
  661.     int   i, year, day, hours, minutes;
  662.     char  *month, *m;
  663.     ulong average, work;
  664.     unsigned exportSector();
  665.  
  666.     getdate(&year, &month, &day, &hours, &minutes);
  667.     if (hours >= 12)
  668.     m = "pm";
  669.     else
  670.     m = "am";
  671.     if (hours >= 13)
  672.     hours -= 12;
  673.     if (hours == 0)
  674.     hours = 12;
  675.  
  676.     mPrintf("This is %s\n ", &cfg.codeBuf[cfg.nodeTitle]);
  677.     mPrintf("%d%s%02d %d:%02d %s\n", year, month, day, hours, minutes, m);
  678.  
  679.     if (loggedIn) {
  680.     mPrintf(" Logged in as %s\n", logBuf.lbname);
  681.     if (logBuf.lbflags.NET_PRIVS)
  682.         mPrintf(" You have net privileges, %d LD credits\n",
  683.             logBuf.credit);
  684.     }
  685.     mPrintf(" %ld messages,",         cfg.newest-cfg.oldest +1);
  686.     mPrintf(" last is %lu,\n",         cfg.newest          );
  687.     mPrintf(" %dK message space,\n", cfg.maxMSector >> 3     );
  688.     mPrintf(" %d-entry log\n",         cfg.MAXLOGTAB         );
  689.     mPrintf(" %d room slots\n",      MAXROOMS);
  690.     if (cfg.oldest > 1)
  691.     work = cfg.maxMSector;
  692.     else
  693.     work = cfg.catSector;
  694.     work *= 128;
  695.     if (cfg.oldest > 1)
  696.     average = (work) / (cfg.newest - cfg.oldest + 1);
  697.     else
  698.     average = (work) / (cfg.newest);
  699.     mPrintf(" Average message length: %ld\n",  average);
  700.     if (cfg.debug) printf("Sector to write to: %u\n", exportSector());
  701. }
  702.  
  703.  
  704. /************************************************************************/
  705. /*    unspace() copies a filename, removing blanks            */
  706. /************************************************************************/
  707. unspace(from, to)
  708. char *from, *to;
  709. {
  710.     while (*to =  *from++)   if (*to != ' ')   to++;
  711. }
  712.  
  713. /************************************************************************/
  714. /*    wildCard() Do something with the directory            */
  715. /************************************************************************/
  716. #define UFNsIZE     13    /* size of "filename.ext" plus a null.    */
  717.  
  718. wildCard(fn, filename)
  719. int (*fn)();
  720. char *filename;     /* may be ambiguous.  No drive or user numbers. */
  721. {
  722.     int  i, s, strCmp(), fileCount;
  723.     struct {
  724.     char unambig[UFNsIZE];    /* filename */
  725.     } *fp;
  726.     char *FileList, *ls, *filedir();
  727.  
  728.     if (!setSpace(roomBuf.rbdisk, roomBuf.rbdirname)) return;
  729.  
  730.     if (filename[1] != ':')
  731.     ls = FileList = filedir(filename, 0);
  732.  
  733.     if (filename[1] == ':' || !(*FileList)) {
  734.     /* no such file */
  735.     mPrintf("no %s\n ", filename);
  736.     if (strLen(roomBuf.rbdirname) != 0)
  737.         setSpace(roomBuf.rbdisk, "..");
  738.     setSpace(cfg.homeDisk, "");
  739.     if (filename[1] != ':')
  740.         free(ls);
  741.     return;
  742.     }
  743.  
  744.     fp          = msgBuf.mbtext;
  745.     fileCount = 0;
  746.  
  747.     while (*FileList) {
  748.     if (fp > (&msgBuf.mbtext[MAXTEXT-100])) {
  749.         mPrintf("too many files!!\n ");
  750.         setSpace(roomBuf.rbdisk, "..");
  751.         setSpace(cfg.homeDisk, "");
  752.         return;
  753.     }
  754.     strCpy(fp->unambig, FileList);
  755.     while (*FileList) FileList++;
  756.     FileList++;
  757.     fp++;
  758.     fileCount++;
  759.     }
  760.  
  761.     qSort(msgBuf.mbtext, fileCount, UFNsIZE, strCmp);
  762.     outFlag    = OUTOK;
  763.     for (fp = msgBuf.mbtext;  fileCount-- && outFlag != OUTSKIP;  fp++)
  764.     (*fn)(fp);
  765.     if (strLen(roomBuf.rbdirname) != 0)
  766.     setSpace(roomBuf.rbdisk, "..");
  767.     setSpace(cfg.homeDisk, "");
  768.     free(ls);
  769. }
  770.